import { t } from 'i18next'
import { useEffect, useLayoutEffect, useMemo } from 'react'
import shallow from 'zustand/shallow'
import { Alert, confirmModal } from '@/components/Alert'
import { Message, Modal } from '@kedacom/react-next'
import { useRollCallStore } from './store'
import { useMccStore } from '../../store'
import useLock from '@/hooks/useLock'
import { fetchAddRollPlan, fetchDeleteRollPlan, fetchGetRollPlanDetail, fetchGetRollPlanList } from '@/api/manager/roll'
import { fetchUpdatePollPlan } from '@/api/manager/poll'
import { PlanDetailEntity } from '@/api/manager/roll/interface'
import { DropData } from '@/api/manager/type'
import { actionButtonsCancel } from '../../store.actionButton'
import React from 'react'
import type { VariableSizeList as List } from 'react-window'
import { ListTranslator, terminalEntity, TerMode } from './translator'
import { Mt, MtEntity } from '@/api/manager/mt'
import { differenceBy, findIndex } from 'lodash-es'

export const useData = () => {
	const meetingMoid = useMccStore((state) => state.mccInfo.meetingMoid)
	const {
		list,
		update,
		state,
		planOptions,
		preName,
		planValue,
		name,
		testName,
		getRollCallInfo,
		initRollCallerList,
		initGetRollCallInfoCallBack,
		resetSearchInput,
		saveRollCallBeforeStart,
		initPollSchema,
		renderRollcalleeList,
		isSearch,
		dropMtInSearch,
		changeCalleeList,
		getCurRollCaller,
		saveRollcalleeList,
	} = useRollCallStore(
		(state) => ({
			saveRollcalleeList: state.saveRollcalleeList,
			isSearch: state.isSearch,
			dropMtInSearch: state.dropMtInSearch,
			changeCalleeList: state.changeCalleeList,
			getCurRollCaller: state.getCurRollCaller,
			list: state.list,
			state: state.state,
			planOptions: state.planOptions,
			preName: state.preName,
			planValue: state.planValue,
			modeOptions: state.modeOptions,
			modeValue: state.modeValue,
			callerOptions: state.callerOptions,
			callerValue: state.callerValue,
			inputKeyUp: state.inputKeyUp,
			roll_call_sign_enable: state.roll_call_sign_enable,
			members: state.members,
			membersDataBackup: state.membersDataBackup,
			isEdit: state.isEdit,
			mode: state.mode,
			name: state.name,
			update: state.update,
			getPlanPara: state.getPlanPara,
			change_plan: state.change_plan,
			openShow: state.openShow,
			testName: state.testName,
			toggleClick: state.toggleClick,
			saveStartList: state.saveStartList,
			cur_roll_callee: state.cur_roll_callee,
			changeSignResultBtn: state.changeSignResultBtn,
			checkLimits: state.checkLimits,
			showOrHideRollcallUpOrNextBtn: state.showOrHideRollcallUpOrNextBtn,
			enableSignResultBtn: state.enableSignResultBtn,
			getRollcallee: state.getRollcallee,
			getRollCallInfo: state.getInfo,
			initRollCallerList: state.initRollCallerList,
			addUserState: state.addUserState,
			setMtSelected: state.setMtSelected,
			initGetRollCallInfoCallBack: state.initGetRollCallInfoCallBack,
			resetSearchInput: state.resetSearchInput,
			saveRollCallBeforeStart: state.saveRollCallBeforeStart,
			initPollSchema: state.initPollSchema,
			renderRollcalleeList: state.renderRollCalleeList,
		}),
		shallow
	)
	/**轮询状态下禁止操作*/
	const disabled = useMemo(() => state === 1, [state])
	/**初始化加载数据*/
	useEffect(() => {
		resetSearchInput()
		/**初始化点名人下拉列表 */
		initRollCallerList()
		/**向服务器拉取点名信息，根据点名信息初始化页面 */
		getRollCallInfo(initGetRollCallInfoCallBack)
	}, [])
	/**根据全局的设置的预案名称,预案列表获取选中的值*/
	useEffect(() => {
		var value = planOptions.find((item) => item.label === preName)?.value ?? '0'
		update({ planValue: value })
	}, [preName, planOptions])
	/**点击保存预案(清空输入框名称/打开模态框)*/
	const savePlan = async () => {
		planValue === '0' ? update({ name: '', isSavePlanOpen: true }) : updatePlan()
	}
	/**更新预案*/
	const updatePlan = useLock(async () => {
		const detail = await fetchGetRollPlanDetail(meetingMoid, planValue)
		if (detail.success) {
			updatePlanCallBack(detail)
		} else {
			updatePlanCallBack({
				mode: 1, //	integer	轮询模式。1-视频轮询；3-音视频轮询
				id: '',
				keep_time: 30, //轮询间隔时间（秒
				members: [], //轮询成员
				name: '', // 预案名称
				num: 0, //轮询次数，0无限次轮询
			})
		}
	})
	const updatePlanCallBack = async (_data: PlanDetailEntity) => {
		const members = list.map((item) => {
			return {
				name: item.mcc.name, // 名称
				account: item.mcc.account, // 帐号
				account_type: item.mcc.accountType, // 帐号类型 1-moid；4-非系统邮箱；5-e164号；6-电话；7-ip地址；8-别名@ip(监控前端)
				conf_e164: item.mtKey && `${item.mtKey}`.includes('_') ? item.mcc.confE164 : undefined, //会议e164号，级联会议时为本级会议e164号
			}
		})
		let params = Object.assign({}, _data, { id: planValue, members: members })
		const res = await fetchUpdatePollPlan(meetingMoid, planValue, params)
		res.success ? Message.info(t('预案保存成功')) : Alert(res.description || t('预案保存失败'))
		res.success && loadPlanData(preName)
	}
	/**新增预案*/
	const addPlan = useLock(async () => {
		const _name_flag = testName(name)
		if (_name_flag) {
			return
		}
		const members = list.map((item) => {
			return {
				name: item.mcc.name, // 名称
				account: item.mcc.account, // 帐号
				account_type: item.mcc.accountType, // 帐号类型 1-moid；4-非系统邮箱；5-e164号；6-电话；7-ip地址；8-别名@ip(监控前端)
				conf_e164: item.mtKey && `${item.mtKey}`.includes('_') ? item.mcc.confE164 : undefined, //会议e164号，级联会议时为本级会议e164号
			}
		})
		const params = {
			mode: 1, //	integer	轮询模式。1-视频轮询；3-音视频轮询
			id: '',
			keep_time: 30, //轮询间隔时间（秒
			members: members, //轮询成员
			name: name, // 预案名称
			num: 0, //轮询次数，0无限次轮询
		}
		const res = await fetchAddRollPlan(meetingMoid, params)
		if (res.success) {
			initPollSchema(name)
			Message.info(t('预案保存成功'))
			update({ isSavePlanOpen: false })
		} else {
			Alert(res.description || t('预案保存失败'))
		}
	})
	/**删除预案 */
	const deletePlan = async (item: { label: string; value: string }) => {
		const meetingMoid = useMccStore.getState().mccInfo.meetingMoid
		/**判断删除的预案是否是当前选中的*/
		let isCur = planValue === item.value ? true : false
		let _plan_option = planOptions.filter((v) => item.value !== v.value)
		confirmModal({
			msg: t('是否确定删除{{name}}？', { name: item.label }),
			onOk: async () => {
				const res = await fetchDeleteRollPlan(meetingMoid, item.value)
				if (res.success) {
					isCur && update({ preName: t('不使用预案'), planOptions: _plan_option })
					!isCur && update({ planOptions: _plan_option })
				} else {
					Alert(res.description || '')
				}
			},
		})
	}
	/**切换预案*/
	const changePlan = async (value: string) => {
		const item = planOptions.find((item) => item.value === value)
		update({ planValue: value, preName: item?.label })
		if (value !== '0') {
			saveRollCallBeforeStart()
			const res = await fetchGetRollPlanDetail(meetingMoid, value)
			if (res.success) {
				Message.info(t('预案载入成功'))
				renderRollcalleeList(res.members ?? [])
				saveRollcalleeList()
			} else {
				Alert(t('获取点名轮询预案失败'))
			}
		} else {
			/**切换到不使用预案 */
			saveRollCallBeforeStart()
			update({
				list: [],
				callerValue: '-1',
				state: 0,
			})
		}
	}
	/**轮询预案,初始化轮询预案不传值，其他点击保存轮询预案均传值 */
	const loadPlanData = async (planName?: string) => {
		const res = await fetchGetRollPlanList(meetingMoid)
		if (res.success && res.data) {
			const planData = res.data
			let arr = planData ? planData.map((item) => ({ label: item.name, value: item.id })) : []
			arr.unshift({ label: t('不使用预案'), value: '0' })
			update({ planOptions: arr })
			/**新增预案,更新预案(刷新预案列表)*/
			planName && update({ preName: planName })
		} else {
			Alert(t('获取预案失败'))
		}
	}
	//拖拽
	const handleDrop = (dataTransfer: DropData & { data?: { remark?: string } }, index: number) => {
		if (dataTransfer && dataTransfer.data && dataTransfer.data.mt) {
			let mt = dataTransfer.data.mt
			let from = dataTransfer.from
			if ((mt.isMt || mt.conf_level == 1 || (!mt.isMt && mt.online)) && from !== 'roll') {
				if (!mt.isMt) {
					//过滤掉会议
					Alert(t('会议不能进入轮询列表'))
					return false
				}
				if (list.length >= 5000 /**点名轮询5000方 */) {
					Alert(t('参与点名与会方最多为5000方'))
					return
				}
				//搜索过程中 放置dom 需要清空搜索然后在添加
				if (isSearch) {
					dropMtInSearch([new Mt(mt)])
					return
				}
				const rollcallerMT = getCurRollCaller()
				if (rollcallerMT && rollcallerMT.mt_key == mt.mt_key) {
					Alert(t('终端{{name}}和当前点名人相同，进入被点名人列表失败', { name: mt.name }))
					return
				}
				dealDrop({
					mts: ListTranslator([mt]),
					from: dataTransfer.from,
					dropIndex: index,
				})
			} else if (from === 'roll') {
				if (!isSearch) {
					//点名轮询中被点人的拖动（需做特殊处理)
					dealDrop({
						mts: ListTranslator([
							Object.assign(mt, { remark: dataTransfer.data.remark || '' }) as MtEntity & {
								remark?: string
							},
						]),
						from: dataTransfer.from,
						dropIndex: index,
					})
				}
			}
		}
	}
	// //拖拽进入列表
	const dealDrop = ({ mts, from, dropIndex }: terminalEntity) => {
		if (from !== 'roll') {
			const insertList = differenceBy(mts, list, (x) => x.mtKey)
			if (insertList.length === 0) return //重复添加
			let newList = [...list.slice(0, dropIndex), ...insertList, ...list.slice(dropIndex)]
			update({ list: newList })
			changeCalleeList()
		} else {
			const baseList = differenceBy(list, mts, (x) => x.mtKey)
			let insertToBaseIndex = dropIndex
			const baseListMtKeys = baseList.map((l) => l.mtKey)
			const nextFirstBaseListIndex = findIndex(list, (l) => baseListMtKeys.includes(l.mtKey), dropIndex)
			if (nextFirstBaseListIndex === -1) {
				insertToBaseIndex = baseList.length
			} else {
				insertToBaseIndex = baseList.findIndex((l) => l.mtKey === list[nextFirstBaseListIndex].mtKey)
			}
			update({
				list: [...baseList.slice(0, insertToBaseIndex), ...mts, ...baseList.slice(insertToBaseIndex)],
			})
			changeCalleeList()
		}
	}
	/**返回操作*/
	const handleReturnBack = () => {
		useMccStore.getState().setCurPage('mcc_main')
		actionButtonsCancel()
	}
	return {
		/**加载预案数据 */
		loadPlanData,
		/**切换预案 */
		changePlan,
		/**删除预案 */
		deletePlan,
		handleDrop,
		/**返回操作设置主页 */
		handleReturnBack,
		/**保存预案 */
		savePlan,
		/**新增预案 */
		addPlan,
		disabled,
	}
}
export const useHeight = (list: TerMode[]) => {
	let ref = React.createRef<List>()
	let height: number[] = []
	height = useMemo(
		() =>
			list.map((x) => {
				if (x.remark) {
					return 55
				}
				return 32
			}),
		[list]
	)
	useLayoutEffect(() => {
		if (ref.current) {
			ref.current.resetAfterIndex(0, false)
		}
	})
	return { height, ref }
}
